package com.julang.check.controller;

import com.julang.check.annotation.NotNeedToken;
import com.julang.check.utils.Result;
import com.julang.check.utils.SingnalData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * @author 赵自强
 * */
@Controller
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class GlobalExceptionHandler extends AbstractErrorController {
	private final ErrorProperties errorProperties;

	@Autowired
	public GlobalExceptionHandler(ErrorAttributes errorAttributes, ServerProperties serverProperties) {
		super(errorAttributes);
		this.errorProperties = serverProperties.getError();
	}

	@Override
	public String getErrorPath() {
		return this.errorProperties.getPath();
	}

	@RequestMapping(
			produces = {"text/html"}
	)
	@ResponseBody
	@NotNeedToken
	public String errorHtml(HttpServletRequest request, HttpServletResponse response) {
		StringBuilder stringBuilder = new StringBuilder();
		Map<String, Object> body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL));
		String s = (body.getOrDefault("trace", "") + "");
		System.out.println("a");
		System.out.println(s);
		System.out.println("b");
		String[] traces = s.split("\r\n");
		System.out.println("size:" + traces.length);
		stringBuilder.append("<!DOCTYPE html>");
		stringBuilder.append("<html>");
		stringBuilder.append("<head>");
		stringBuilder.append("<title>页面出现错误</title>");
		stringBuilder.append("</head>");
		stringBuilder.append("<body style=\"background-color: #cccccc\">");
		stringBuilder.append("<div style=\"width: 80%;margin-left: auto;margin-right: auto\">");
		stringBuilder.append("<div style=\"margin-left: 40px\">");
		stringBuilder.append("<h2>当前请求出现错误:  " + body.getOrDefault("error", "null") + "</h2>");
		stringBuilder.append("<h4>错误信息:  " + body.getOrDefault("message", "null") + "</h4>");
		stringBuilder.append("<h4>错误路由信息:  " + body.getOrDefault("path", "null") + "</h4>");
		stringBuilder.append("<h4>错误码:  " + body.getOrDefault("status", "null") + "</h4>");
		stringBuilder.append("<h4>时间:  " + SingnalData.df.format(new Date()) + "</h4>");
		stringBuilder.append("</div>");
		if (traces.length > 1) {
			stringBuilder.append("<div style=\"border: 2px solid #40a9ff;word-break:break-all;background-color: " +
                    "#d0ddf0;border-radius: 10px;font-size: 19px;padding-left: 40px;\">");
			for (int i = 0; i < traces.length; i++) {
				stringBuilder.append("<p>" + traces[i] + "</p>");
			}
			stringBuilder.append("</div>");
		}
		stringBuilder.append("</div>");
		stringBuilder.append("<div style=\"height: 100px\"></div>");
		stringBuilder.append("</body>");
		stringBuilder.append("</html>");
		return stringBuilder.toString();
	}

	@RequestMapping
	@ResponseBody
	@NotNeedToken
	public Result errorJson(HttpServletRequest request) {
		Map<String, Object> body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL));
		Result result = new Result();
		result.setData(body);
		result.setResult(false);
		String errors = (String) body.getOrDefault("trace", "");
		System.out.println(errors);
		result.setMessage("" + body.getOrDefault("message", "暂无信息"));
		HttpStatus status = this.getStatus(request);
		result.setCode(status.value());
		return result;
	}

	protected boolean isIncludeStackTrace(HttpServletRequest request, MediaType produces) {
		ErrorProperties.IncludeStacktrace include = this.getErrorProperties().getIncludeStacktrace();
		if (include == ErrorProperties.IncludeStacktrace.ALWAYS) {
			return true;
		} else {
			return include == ErrorProperties.IncludeStacktrace.ON_TRACE_PARAM ? this.getTraceParameter(request) :
                    false;
		}
	}

	protected ErrorProperties getErrorProperties() {
		return this.errorProperties;
	}


}
